; messages
(define-constant *M-Queue-is-empty*     0x01)
(define-constant *M-Queue-enqueue*      0x02)
(define-constant *M-Queue-insert-head*  0x03)
(define-constant *M-Queue-dequeue*      0x04)

; make-Queue
(define (make-Queue head tail)
	(define is-empty? (lambda () (null? head)))
	(lambda (message)
		(case message
			((*M-Queue-is-empty*) is-empty?)
			((*M-Queue-enqueue*)
				(lambda (data)
					(if (is-empty?) 
						(begin 
							(set! head (cons data ())) 
							(set! tail head)) 
						(begin 
							(set-cdr! tail (cons data ())) 
							(set! tail (cdr tail))))))
			((*M-Queue-insert-head*)
				(lambda (data)
					(if (is-empty?) 
						(begin 
							(set! head (cons data ())) 
							(set! tail head)) 
						(set-cdr! head (cons data head)))))
			((*M-Queue-dequeue*)
				(lambda ()
					(if (is-empty?) 
						()
						(let ((data (car head))) 
							(set! head (cdr head))
							(if (null? head) (set! tail ()))
							data))))
			(else ()))))

